﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Workflow;
using System.Workflow.ComponentModel.Compiler;
using CrmContrib.Workflow.Activities.SSRSExecution;

namespace CrmContrib.Workflow.Activities.Reporting
{
    [CrmWorkflowActivity("Generate External Report", "CrmContrib \\ Reporting")]
    public class GenerateExternalReportActivity : Activity
    {
        [CrmInput("Report Path")]
        [ValidationOption(ValidationOption.Required)]
        public string ReportPath
        {
            get { return (string)base.GetValue(ReportPathProperty); }
            set { base.SetValue(ReportPathProperty, value); }
        }

        public static readonly DependencyProperty ReportPathProperty = DependencyProperty.Register("ReportPath", typeof(string), typeof(GenerateExternalReportActivity));

        [CrmInput("Report Parameter 1")]
        [ValidationOption(ValidationOption.Required)]
        public string ReportParameter1
        {
            get { return (string)base.GetValue(ReportParameter1Property); }
            set { base.SetValue(ReportParameter1Property, value); }
        }

        public static readonly DependencyProperty ReportParameter1Property = DependencyProperty.Register("ReportParameter1", typeof(string), typeof(GenerateExternalReportActivity));

        [CrmInput("Report Parameter 1 Value")]
        [ValidationOption(ValidationOption.Required)]
        public string ReportParameter1Value
        {
            get { return (string)base.GetValue(ReportParameter1ValueProperty); }
            set { base.SetValue(ReportParameter1ValueProperty, value); }
        }

        public static readonly DependencyProperty ReportParameter1ValueProperty = DependencyProperty.Register("ReportParameter1Value", typeof(string), typeof(GenerateExternalReportActivity));

        [CrmInput("Render As")]
        [ValidationOption(ValidationOption.Required)]
        public string RenderAs
        {
            get { return (string)base.GetValue(RenderAsProperty); }
            set { base.SetValue(RenderAsProperty, value); }
        }

        public static readonly DependencyProperty RenderAsProperty = DependencyProperty.Register("RenderAs", typeof(string), typeof(GenerateExternalReportActivity));

        [CrmInput("Report Server URL")]
        [ValidationOption(ValidationOption.Required)]
        public string ReportServerUrl
        {
            get { return (string)base.GetValue(ReportServerUrlProperty); }
            set { base.SetValue(ReportServerUrlProperty, value); }
        }

        public static readonly DependencyProperty ReportServerUrlProperty = DependencyProperty.Register("ReportServerUrl", typeof(string), typeof(GenerateExternalReportActivity));

        private void SetExecutionParameters(ReportExecutionService reportService, ExecutionInfo reportInfo)
        {
            reportService.SetExecutionParameters(new []{ new ParameterValue { Name = ReportParameter1, Value = ReportParameter1Value } }, "en-US");
        }

        /// <summary>
        /// Renders the report and saves the output into the FileRegistry.
        /// </summary>
        /// <param name="reportPath"></param>
        /// <returns></returns>
        private Guid RenderReport(string reportPath)
        {
            byte[] output;

            using (var rs = new ReportExecutionService())
            {
                string extension;
                string mimetype;
                string encoding;
                Warning[] warnings;
                string[] streamIds;
                string reportFormat = RenderAs;
                string deviceInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";

                rs.UseDefaultCredentials = true;
                rs.Url = ReportServerUrl;

                rs.ExecutionHeaderValue = new ExecutionHeader();
                ExecutionInfo executionInfo = rs.LoadReport(reportPath, null);  //there could be connection issues here if default connection string in report does not exist
                SetExecutionParameters(rs, executionInfo);

                output = rs.Render(reportFormat, deviceInfo, out extension, out mimetype, out encoding, out warnings, out streamIds);
            }

            return FileRegistry.AddFile(output).FileID;
        }

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            FileID = RenderReport(ReportPath).ToString();
            return base.Execute(executionContext);
        }

        [CrmOutput("File ID")]
        public string FileID
        {
            get { return (string)base.GetValue(FileIDProperty); }
            set { base.SetValue(FileIDProperty, value); }
        }

        public static readonly DependencyProperty FileIDProperty = DependencyProperty.Register("FileID", typeof(string), typeof(GenerateExternalReportActivity));
    }
}
